<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>src/node/class.node.animatedSprite.js - sceneGraph.js</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
    <link rel="shortcut icon" type="image/png" href="../assets/favicon.png">
    <script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
</head>
<body class="yui3-skin-sam">

<div id="doc">
    <div id="hd" class="yui3-g header">
        <div class="yui3-u-3-4">
            
                <h1><img src="../../logo/logoCGSG_256x57.png" title="sceneGraph.js"></h1>
            
        </div>
        <div class="yui3-u-1-4 version">
            <em>API Docs for: v2.1.0</em>
        </div>
    </div>
    <div id="bd" class="yui3-g">

        <div class="yui3-u-1-4">
            <div id="docs-sidebar" class="sidebar apidocs">
                <div id="api-list">
    <h2 class="off-left">APIs</h2>
    <div id="api-tabview" class="tabview">
        <ul class="tabs">
            <li><a href="#api-classes">Classes</a></li>
            <li><a href="#api-modules">Modules</a></li>
        </ul>

        <div id="api-tabview-filter">
            <input type="search" id="api-filter" placeholder="Type to filter APIs">
        </div>

        <div id="api-tabview-panel">
            <ul id="api-classes" class="apis classes">
            
                <li><a href="../classes/CGSG.html">CGSG</a></li>
            
                <li><a href="../classes/CGSGAccordion.html">CGSGAccordion</a></li>
            
                <li><a href="../classes/CGSGAnimationManager.html">CGSGAnimationManager</a></li>
            
                <li><a href="../classes/CGSGAnimationMethod.html">CGSGAnimationMethod</a></li>
            
                <li><a href="../classes/CGSGBindEntry.html">CGSGBindEntry</a></li>
            
                <li><a href="../classes/CGSGButtonMode.html">CGSGButtonMode</a></li>
            
                <li><a href="../classes/CGSGCollisionGhostOnDemandTester.html">CGSGCollisionGhostOnDemandTester</a></li>
            
                <li><a href="../classes/CGSGCollisionManager.html">CGSGCollisionManager</a></li>
            
                <li><a href="../classes/CGSGCollisionMethod.html">CGSGCollisionMethod</a></li>
            
                <li><a href="../classes/CGSGCollisionRegionTester.html">CGSGCollisionRegionTester</a></li>
            
                <li><a href="../classes/CGSGCollisionTesterFactory.html">CGSGCollisionTesterFactory</a></li>
            
                <li><a href="../classes/CGSGColor.html">CGSGColor</a></li>
            
                <li><a href="../classes/CGSGCSSManager.html">CGSGCSSManager</a></li>
            
                <li><a href="../classes/CGSGDimension.html">CGSGDimension</a></li>
            
                <li><a href="../classes/CGSGEvent.html">CGSGEvent</a></li>
            
                <li><a href="../classes/CGSGEventManager.html">CGSGEventManager</a></li>
            
                <li><a href="../classes/CGSGHandleBox.html">CGSGHandleBox</a></li>
            
                <li><a href="../classes/CGSGImgManager.html">CGSGImgManager</a></li>
            
                <li><a href="../classes/CGSGInterpolator.html">CGSGInterpolator</a></li>
            
                <li><a href="../classes/CGSGInterpolatorLinear.html">CGSGInterpolatorLinear</a></li>
            
                <li><a href="../classes/CGSGInterpolatorTCB.html">CGSGInterpolatorTCB</a></li>
            
                <li><a href="../classes/CGSGKeyFrame.html">CGSGKeyFrame</a></li>
            
                <li><a href="../classes/CGSGMap.html">CGSGMap</a></li>
            
                <li><a href="../classes/CGSGMask.html">CGSGMask</a></li>
            
                <li><a href="../classes/CGSGMaskCache.html">CGSGMaskCache</a></li>
            
                <li><a href="../classes/CGSGMaskClip.html">CGSGMaskClip</a></li>
            
                <li><a href="../classes/CGSGMath.html">CGSGMath</a></li>
            
                <li><a href="../classes/CGSGNode.html">CGSGNode</a></li>
            
                <li><a href="../classes/CGSGNodeButton.html">CGSGNodeButton</a></li>
            
                <li><a href="../classes/CGSGNodeCircle.html">CGSGNodeCircle</a></li>
            
                <li><a href="../classes/CGSGNodeColorPicker.html">CGSGNodeColorPicker</a></li>
            
                <li><a href="../classes/CGSGNodeCurveTCB.html">CGSGNodeCurveTCB</a></li>
            
                <li><a href="../classes/CGSGNodeDomElement.html">CGSGNodeDomElement</a></li>
            
                <li><a href="../classes/CGSGNodeEllipse.html">CGSGNodeEllipse</a></li>
            
                <li><a href="../classes/CGSGNodeImage.html">CGSGNodeImage</a></li>
            
                <li><a href="../classes/CGSGNodeLine.html">CGSGNodeLine</a></li>
            
                <li><a href="../classes/CGSGNodeSlider.html">CGSGNodeSlider</a></li>
            
                <li><a href="../classes/CGSGNodeSliderHandle.html">CGSGNodeSliderHandle</a></li>
            
                <li><a href="../classes/CGSGNodeSprite.html">CGSGNodeSprite</a></li>
            
                <li><a href="../classes/CGSGNodeSquare.html">CGSGNodeSquare</a></li>
            
                <li><a href="../classes/CGSGNodeTabMenu.html">CGSGNodeTabMenu</a></li>
            
                <li><a href="../classes/CGSGNodeText.html">CGSGNodeText</a></li>
            
                <li><a href="../classes/CGSGNodeWebview.html">CGSGNodeWebview</a></li>
            
                <li><a href="../classes/CGSGParticle.html">CGSGParticle</a></li>
            
                <li><a href="../classes/CGSGParticleEmitter.html">CGSGParticleEmitter</a></li>
            
                <li><a href="../classes/CGSGParticleSystem.html">CGSGParticleSystem</a></li>
            
                <li><a href="../classes/CGSGPickNodeMethod.html">CGSGPickNodeMethod</a></li>
            
                <li><a href="../classes/CGSGPosition.html">CGSGPosition</a></li>
            
                <li><a href="../classes/CGSGRegion.html">CGSGRegion</a></li>
            
                <li><a href="../classes/CGSGRotation.html">CGSGRotation</a></li>
            
                <li><a href="../classes/CGSGScale.html">CGSGScale</a></li>
            
                <li><a href="../classes/CGSGSceneGraph.html">CGSGSceneGraph</a></li>
            
                <li><a href="../classes/CGSGSection.html">CGSGSection</a></li>
            
                <li><a href="../classes/CGSGTimeline.html">CGSGTimeline</a></li>
            
                <li><a href="../classes/CGSGTraverser.html">CGSGTraverser</a></li>
            
                <li><a href="../classes/CGSGVector2D.html">CGSGVector2D</a></li>
            
                <li><a href="../classes/CGSGView.html">CGSGView</a></li>
            
                <li><a href="../classes/CGSGWEBVIEWMODE.html">CGSGWEBVIEWMODE</a></li>
            
                <li><a href="../classes/CGSGWrapMode.html">CGSGWrapMode</a></li>
            
                <li><a href="../classes/GLOBAL_CONSTANTS.html">GLOBAL_CONSTANTS</a></li>
            
                <li><a href="../classes/GLOBAL_METHODS.html">GLOBAL_METHODS</a></li>
            
                <li><a href="../classes/GLOBAL_PROPERTIES.html">GLOBAL_PROPERTIES</a></li>
            
                <li><a href="../classes/UTIL_ARRAY.html">UTIL_ARRAY</a></li>
            
                <li><a href="../classes/WUICCGSGNodeImageFactory.html">WUICCGSGNodeImageFactory</a></li>
            
            </ul>

            <ul id="api-modules" class="apis modules">
            
                <li><a href="../modules/Animation.html">Animation</a></li>
            
                <li><a href="../modules/Collision.html">Collision</a></li>
            
                <li><a href="../modules/Math.html">Math</a></li>
            
                <li><a href="../modules/Node.html">Node</a></li>
            
                <li><a href="../modules/ParticleSystem.html">ParticleSystem</a></li>
            
                <li><a href="../modules/Scene.html">Scene</a></li>
            
                <li><a href="../modules/Util.html">Util</a></li>
            
            </ul>
        </div>
    </div>
</div>

            </div>
        </div>
        <div class="yui3-u-3-4">
                <div id="api-options">
        Show:
        <label for="api-show-inherited">
            <input type="checkbox" id="api-show-inherited" checked>
            Inherited
        </label>

        <label for="api-show-protected">
            <input type="checkbox" id="api-show-protected">
            Protected
        </label>

        <label for="api-show-private">
            <input type="checkbox" id="api-show-private">
            Private
        </label>
        <label for="api-show-deprecated">
            <input type="checkbox" id="api-show-deprecated">
            Deprecated
        </label>

    </div>


            <div class="apidocs">
                <div id="docs-main">
                    <div class="content">
                        <h1 class="file-heading">File: src/node/class.node.animatedSprite.js</h1>

<div class="file">
    <pre class="code prettyprint linenums">
/*
 * Copyright (c) 2014 Gwennael Buchet
 *
 * License/Terms of Use
 *
 * Permission is hereby granted, free of charge and for the term of intellectual property rights on the Software, to any
 * person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to use, copy, modify
 * and propagate free of charge, anywhere in the world, all or part of the Software subject to the following mandatory conditions:
 *
 *   •    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 *  Any failure to comply with the above shall automatically terminate the license and be construed as a breach of these
 *  Terms of Use causing significant harm to Gwennael Buchet.
 *
 *  THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 *  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 *  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 *  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *  Except as contained in this notice, the name of Gwennael Buchet shall not be used in advertising or otherwise to promote
 *  the use or other dealings in this Software without prior written authorization from Gwennael Buchet.
 *
 *  These Terms of Use are subject to French law.
 */

/**
 * A CGSGNodeSprite represent an animated sprite, with all animations in the image
 *
 * @class CGSGNodeSprite
 * @extends CGSGNode
 * @module Node
 * @constructor
 * @param {Number} x Relative position on X
 * @param {Number} y Relative position on Y
 * @param {String} urlImage URL of the image. Can be null to be set later
 * @type {CGSGNodeSprite}
 * @author Gwennael Buchet (gwennael.buchet@gmail.com)
 */
var CGSGNodeSprite = CGSGNode.extend(
    {
        initialize: function (x, y, urlImage) {
            this._super(x, y);

            /**
             * @property classType
             * @type {String}
             */
            this.classType = &quot;CGSGNodeSprite&quot;;

            /**
             * array of animations
             * @property listAnimations
             * @type {Array}
             */
            this.listAnimations = [];
            /**
             * @property currentAnimation
             * @default null
             * @type {Object}
             */
            this.currentAnimation = null;
            /**
             * @property isProportionalResize
             * @default true
             * @type {Boolean}
             */
            this.isProportionalResize = true;

            /**
             * Current animated frame
             * @property _currentFrame
             * @private
             * @type {Number}
             */
            this._currentFrame = 0;
            /**
             * Whether the sprite is being animated or not
             * @property _isPlaying
             * @private
             * @readonly
             * @type {Boolean}
             */
            this._isPlaying = false;

            /**
             * Number of loops for the current animation. if -1 then it&#x27;s an infinite loop.
             * @property _numberOfLoops
             * @private
             * @type {Number}
             */
            this._numberOfLoops = 1;
            /**
             * Current loop number
             * @property _currentLoop
             * @private
             * @type {Number}
             */
            this._currentLoop = 0;

            /**
             * URL of the image
             * @property _urlImage
             * @type {String}
             * @private
             */
            this._urlImage = urlImage;
            /**
             * The image object itself
             * @property _img
             * @type {Image}
             * @private
             */
            this._img = new Image();

            /**
             * @property _isLoaded
             * @type {Boolean}
             * @private
             */
            this._isLoaded = false;

            /**
             * Handler function fired when the image is loaded
             * @property onLoadEnd
             * @default null
             * @type {Function}
             */
            this.onLoadEnd = null;
            /**
             * Handler function fired after an animation loop is ended
             * @property onAnimationEnd
             * @default null
             * @type {Function}
             */
            this.onAnimationEnd = null;
            /**
             * Handler function fired before an animation loop start
             * @property onAnimationStart
             * @default null
             * @type {Function}
             */
            this.onAnimationStart = null;

            ///// INITIALIZATION //////
            //finally load the image
            if (this._urlImage !== null &amp;&amp; this._urlImage != &quot;&quot;) {
                this._img.onload = this._createDelegate(this, this._onImageLoaded);
                this._img.src = this._urlImage;
            }
        },

        /**
         * Used to call delegate method when the image is finally loaded
         * @private
         * @method _createDelegate
         * @param objectContext
         * @param delegateMethod
         * @return {Function}
         */
        _createDelegate: function (objectContext, delegateMethod) {
            return function () {
                return delegateMethod.call(objectContext);
            }
        },

        /**
         * fired when the image is loaded.
         * Check the dimension of the image and fired the onLoadEnd event
         * @protected
         * @method _onImageLoaded
         */
        _onImageLoaded: function () {
            this.checkDimension();
            this._isLoaded = true;
            //this._initShape();
            if (this.onLoadEnd !== null) {
                CGSG.eventManager.dispatch(this, cgsgEventTypes.ON_LOAD_END, new CGSGEvent(this, {node: this}));
            }
            this.invalidate();
        },

        /**
         * To be overrided when the image failed to load
         * @method _onImageError
         * @protected
         */
        _onImageError: function () {
            console.log(&quot;Error while loading image : &quot; + this._urlImage);
        },

        /**
         * Check the true dimension of the image and fill the this.dimension property with it,
         * only if dimension is not already defined in the constructor
         * @method checkDimension
         */
        checkDimension: function () {
            //if no width or height are specified in the constructor
            if (this.dimension.width &lt;= 0 &amp;&amp; this.dimension.height &lt;= 0) {
                this.dimension.width = this._img.width;
                this.dimension.height = this._img.height;
            }
        },

        /**
         * Set the image for this animated sprite.
         * @example
         *
         * this.pingoo = new CGSGNodeSprite(60, 60, null, this.context);
         * this.pingoo.isDraggable = true;
         * //name, speed, frames, sliceX, sliceY, width, height, framesPerLine
         * this.pingoo.addAnimation(&quot;front&quot;, 6, 4, 476, 0, 34, 34, 4);
         * this.pingoo.play(&quot;front&quot;, null);
         *
         * //now, load the image containing the sprite sheet.
         * //The affectation to the sprite will be done in the loaded handler function
         * this.spriteSheet = new Image();
         * this.spriteSheet.onload = this.onImageLoaded();
         * this.spriteSheet.src = &quot;images/board.png&quot;;
         *
         * onImageLoaded : function () {
         *     this.pingoo.setImage(this.spriteSheet);
         *     this.numbers.setImage(this.spriteSheet);
         *   this.water.setImage(this.spriteSheet);
         * }
         *
         * @method setImage
         * @param {Image} newImage new Image object. Must be an already loaded one
         */
        setImage: function (newImage) {
            this._img = newImage;
            if (cgsgExist(this._img)) {
                this._urlImage = this._img.src;
                this._isLoaded = true;
                this.invalidate();
            }
        },

        /**
         * Go to the next frame of the current animation
         * @public
         * @method goToNextFrame
         */
        goToNextFrame: function () {
            this._currentFrame += 1.0 / this.currentAnimation.speed;
            var isEndOfLoop = false;
            if (this._currentFrame &gt;= this.currentAnimation.frames) {
                isEndOfLoop = true;
            }

            //end of animation if the previous modulo returns to frame 0
            if (isEndOfLoop) {
                //if this is the end (&quot;... my only friend.. la la...&quot;) of the loop, stop it
                if (this._numberOfLoops &lt; 0 || this._currentLoop &lt; this._numberOfLoops) {
                    this._currentLoop++;
                    this.goToFirstFrame();
                }
                else {
                    this.goToLastFrame();
                    this.stop();
                }
            }

            this.invalidate();
        },

        /**
         * Go to the previous frame of the current animation
         * @public
         * @method goToPreviousFrame
         */
        goToPreviousFrame: function () {
            this._currentFrame -= this.currentAnimation.speed;
            var isStartOfLoop = false;
            if (this._currentFrame &lt; 0) {
                isStartOfLoop = true;
            }

            //end of animation if the previous modulo returns to frame 0
            if (isStartOfLoop) {
                //if this is the end (&quot;... my only friend.. la la...&quot;) of the loop, stop it
                if (this._numberOfLoops &lt;= 0 || this._currentLoop &gt;= 0) {
                    this._currentLoop--;
                    this.goToLastFrame();
                }
                else {
                    this.goToFirstFrame();
                    this.stop();
                }
            }

            this.invalidate();
        },

        /**
         * Go to the first frame of the current loop
         * @public
         * @method goToFirstFrame
         */
        goToFirstFrame: function () {
            this._currentFrame = 0;
            this.invalidate();
        },

        /**
         * Go to the last frame of the current loop
         * @public
         * @method goToLastFrame
         */
        goToLastFrame: function () {
            this._currentFrame = this.currentAnimation.frames - 1;
            this.invalidate();
        },

        /**
         * Must be defined to allow the scene graph to render the image nodes
         * @protected
         * @param c {CanvasRenderingContext2D} The context to render on
         * @method render
         * */
        render: function (c) {
            if (this._isLoaded &amp;&amp; this._img.src != &quot;&quot;) {

                //compute the current slice of the current sprite
                if (cgsgExist(this.currentAnimation)) {
                    c.globalAlpha = this.globalAlpha;

                    var slice = this.currentAnimation.slices[Math.floor(this._currentFrame)];

                    c.drawImage(
                        this._img, // image
                        slice.x,
                        slice.y, // start position on the image
                        this.currentAnimation.width,
                        this.currentAnimation.height, // dimension of the sprite
                        0,
                        0,
                        // position on the screen. let it to [0,0] because the &#x27;beforeRender&#x27; function will translate the image
                        this.dimension.width,
                        this.dimension.height
                    );

                    if (this.lineWidth &gt; 0) {
                        //Next lines are already managed by CGSGNode.
                        //I let it here just to provide an example
                        //context.lineWidth = this.lineWidth;
                        //context.strokeStyle = this.lineColor;
                        c.stroke();
                    }

                    //go to next frame
                    if (this._isPlaying) {
                        this.goToNextFrame();
                        this.invalidate();
                    }
                }
            }
        },

        /**
         * Return position x and y in the image for the slice of the animation and frame passed in parameter.
         * @private
         * @method _getSlice
         * @param {Number} frame
         * @param {Object} animation
         * @return {Object}
         */
        _getSlice: function (frame, animation) {
            var frameX = frame % animation.framesPerLine;
            var frameY = Math.floor(frame / animation.framesPerLine);

            var x = animation.sliceX + frameX * animation.width;
            var y = animation.sliceY + frameY * animation.height;

            return {x: x, y: y};
        },

        /**
         * Add an animation for this sprite
         * @public
         * @method addAnimation
         * @param {String} name Name for this animation
         * @param {Number} speed Number of frames between 2 steps
         * @param {Number} frames Number of frame for this animation
         * @param {Number} sliceX slice position inside the image for this animation
         * @param {Number} sliceY slice position inside the image for this animation
         * @param {Number} width width of 1 frame
         * @param {Number} height height of 1 frame
         * @param {Number} framesPerLine Number of frames per line in the image
         */
        addAnimation: function (name, speed, frames, sliceX, sliceY, width, height, framesPerLine) {
            var animation = {
                name         : name,
                speed        : speed,
                frames       : frames,
                sliceX       : sliceX,
                sliceY       : sliceY,
                width        : width,
                height       : height,
                framesPerLine: framesPerLine,
                slices       : []
            };

            for (var f = 0; f &lt; frames; f++) {
                animation.slices.push(this._getSlice(f, animation));
            }

            this.listAnimations.push(animation);
            if (this.listAnimations.length == 1) {
                this.currentAnimation = animation;
            }

            this.dimension.width = width;
            this.dimension.height = height;
        },

        /**
         * Start an animation
         * @public
         * @method play
         * @param {String} animationName Name of the animation to start
         * @param {Number} loop number of animation loop. Can be null or negative to set infinite loop
         * @return {Boolean} true if the animation exists; false otherwise
         */
        play: function (animationName, loop) {
            if (loop === undefined || loop === null) {
                loop = -1;
            }

            this.currentAnimation = null;
            for (var i = 0; i &lt; this.listAnimations.length; i++) {
                if (this.listAnimations[i].name === animationName) {
                    this.currentAnimation = this.listAnimations[i];
                    this.dimension.width = this.currentAnimation.width;
                    this.dimension.height = this.currentAnimation.height;
                    this.reset();
                    this._numberOfLoops = loop;
                    this._isPlaying = true;
                    this.resizeTo(this.currentAnimation.width, this.currentAnimation.height);
                    if (this.onAnimationStart !== null) {
                        CGSG.eventManager.dispatch(this,
                                                   cgsgEventTypes.ON_ANIMATION_START,
                                                   new CGSGEvent(this,
                                                                 {node: this, animationName: animationName, loop: loop}));
                        //this.onAnimationStart({animationName : animationName, loop : loop});
                    }
                    return true;
                }
            }
            return false;
        },

        /**
         * Stop the current animation and stay on the current frame
         * @public
         * @method stop
         */
        stop: function () {
            this._isPlaying = false;
            if (this.onAnimationEnd !== null) {
                CGSG.eventManager.dispatch(this,
                                           cgsgEventTypes.ON_ANIMATION_END,
                                           new CGSGEvent(this,
                                                         {node: this, animationName: this.currentAnimation.name, loop: this._currentLoop, frame: this._currentFrame}));
                this.onAnimationEnd({animationName: this.currentAnimation.name, loop: this._currentLoop, frame: this._currentFrame});
            }
            this.invalidate();
        },

        /**
         * return to the first frame of the first loop of the current animation
         * @public
         * @method reset
         */
        reset: function () {
            this._currentFrame = 0;
            this._currentLoop = 1;
            this.invalidate();
        },

        /**
         * @public
         * @method copy
         * @return {CGSGNodeSprite} a copy of this node
         */
        copy: function () {
            var node = new CGSGNodeSprite(this.position.x, this.position.y, this._urlImage);
            //call the super method
            node = this._super(node);

            node.listAnimations = [];
            for (var a = 0; a &lt; this.listAnimations.length; a++) {
                node.addAnimation(this.listAnimations[a].name, this.listAnimations[a].speed,
                                  this.listAnimations[a].frames, this.listAnimations[a].sliceX,
                                  this.listAnimations[a].sliceY, this.listAnimations[a].width,
                                  this.listAnimations[a].height, this.listAnimations[a].framesPerLine);
            }

            node.currentAnimation = this.currentAnimation;
            node.isProportionalResize = this.isProportionalResize;

            node._currentFrame = this._currentFrame;
            node._isPlaying = this._isPlaying;
            node._numberOfLoops = this._numberOfLoops;
            node._currentLoop = this._currentLoop;
            node._img = this._img;
            node._isLoaded = this._isLoaded;

            node.onLoadEnd = this.onLoadEnd;
            node.onAnimationEnd = this.onAnimationEnd;
            node.onAnimationStart = this.onAnimationStart;

            if (this._urlImage !== null &amp;&amp; this._urlImage != &quot;&quot;) {
                node._img.onload = node._createDelegate(node, node._onImageLoaded, node.context);
                node._img.src = node._urlImage;
            }

            return node;
        }
    }
);

    </pre>
</div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>
<script src="../assets/js/yui-prettify.js"></script>
<script src="../assets/../api.js"></script>
<script src="../assets/js/api-filter.js"></script>
<script src="../assets/js/api-list.js"></script>
<script src="../assets/js/api-search.js"></script>
<script src="../assets/js/apidocs.js"></script>
</body>
</html>
